#pragma once 

#include <vector>
#include <string>
#include <queue>
#include <unistd.h>
#include "log.hpp"
#include "lockGuard.hpp"
#include "Thread.hpp"



using namespace std ;

const int g_thread_num = 6; 





//创建线程池时。池内线程会开始执行，执行完毕后会等待，等待再次有任务



template<class T>
class ThreadPool
{
private:

    vector<Thread*> _threads ;  // ？ ？ ？ ？ ？ 为啥不变色
    int _num ;  //  ？ ？ ？ ？ ？ 
    queue<T> _task_queue ; // 任务队列


    //单例模式相关 
    static ThreadPool<T>* _thread_ptr;  // ? ? ? ? ? 
    static pthread_mutex_t _mutex;  // ?  ? ? ? 

    pthread_mutex_t _lock ; 
    pthread_cond_t  _cond ;

private:

    // 定义在私有则无法直接创建该类对象
    ThreadPool(int thread_num = g_thread_num)
        :_num(thread_num)
    {
        pthread_mutex_init(&_lock , nullptr);
        pthread_cond_init(&_cond , nullptr) ;
        for(int i = 1 ; i <= _num ; i++)
        {
            _threads.push_back(new Thread(i,routine,this)) ;// 未完成  
        }
    }

    Thread Pool(const ThreadPool<T>& other) = delete ; // 无拷贝构造    // 为什么不允许生产默认拷贝构造

    const ThreadPool<T>& operator=(const ThreadPool<T>& other) = delete ;// 无拷贝构造

public:       

    //单例模式相关 创建对象接口
    static ThreadPool<T>* getThreadPool(int num = g_thread_num)
    {
        //作用是什么 ？ ？ ？ ？ ？ ？ ？ ？ ？ ？  // 是单例
        if(nullptr == _thread_ptr)
        {
            myLockGuard lockguard(&_mutex);
            if(nullptr == _thread_ptr)
            {
                _thread_ptr = new ThreadPool<T>(num);
            }
        }
        return _thread_ptr;
    }


                //启动全部线程 ？？？
    void run()  // 线程初始化的封装的封装……
    {
        for(auto& iter : _threads)
        {
            iter->start();
            logMessage(NORMAL,"%s %s", iter->name().c_str(), "线程启动成功" );
        }
    
    }

    
    //thread_create的回调函数
    //为什么定义成静态 ？ ？ ？ ？ ？
    //因为this指针会被自动传入，且与（void*）类型不匹配导致报错
    static void* routine(void* args)   // 传入的原本是threadPool类型 
    {
        ThreadData* td = (ThreadData*)args ; //为什么可以这样写？ ？ ？ ？ ？ ？ //存疑 ？ ？ ？ ？ ？ ？ ？ // 似乎仅是为了后续调用该类里的函数

        ThreadPool<T>* tp = (ThreadPool<T>*)td->_args ; 
        
        while (true)
        {
            T task ;
            {   
                //这里wait和lock的顺序似乎不对吧? ? ? ? ? ? ? ? ? ? ? ?
                //定义代码块，使lockGuard自动回收的作用生效
                // 访问临界资源  
                myLockGuard lockguard(tp->getMutex()); 

                while(tp->isEmpty()) // 确保 tp->waitCond() 的正确性
                {
                    tp->waitCond();
                }

                task = tp->getTask();  //获取任务
            }

            task(td->_name); //任务执行
        }
    }

    void pushTask(const T& task)
    {
        myLockGuard lockgroud(&_lock) ;
        _task_queue.push(task);
        pthread_cond_signal(&_cond); // ? ?  ? ? ? ? ?  随机唤起一个线程去接取/执行任务
    }

    ~ThreadPool()
    {
        for(auto& iter : _threads)
        {
            iter->join();
            delete iter;
        }
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }


public: // 为了供静态成员函数使用（静态成员函数无this指针无法直接访问类内成员变量）

    pthread_mutex_t* getMutex()
    {
        return &_lock ;
    }

    bool isEmpty()
    {
        return _task_queue.empty();
    }

    void waitCond()
    {
        pthread_cond_wait(&_cond , &_lock);
    }

    T getTask()
    {
        T t = _task_queue.front();
        _task_queue.pop(); // ! ! ! ! ! ! !
        return t ; 
    }

};


// 静态变量初始化 
template <typename T>
ThreadPool<T>* ThreadPool<T>::_thread_ptr = nullptr ; 

template <typename T>
pthread_mutex_t ThreadPool<T>::_mutex = PTHREAD_MUTEX_INITIALIZER ;